import {BlueData} from "./cache/bluedata";

// 自己写的蓝牙代码
class BlueState {
  static DISCOVERY_FINISHED = "android.bluetooth.adapter.action.DISCOVERY_FINISHED"
  static DISCOVERY_FOUND = "android.bluetooth.device.action.FOUND"
  static PAIRING_REQUEST = "android.bluetooth.device.action.PAIRING_REQUEST"
  static BOND_STATE_CHANGED = "android.bluetooth.device.action.BOND_STATE_CHANGED"
  static STATE_CHANGED = "android.bluetooth.adapter.action.STATE_CHANGED"
}

export class BlueTooth {

  constructor() {
    // #ifdef app-plus
    console.log("BlueTooth=====")
    let _intent_filter = plus.android.importClass('android.content.IntentFilter');
    let _bluetooth_adapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");
    this.main_activity = plus.android.runtimeMainActivity();//Android界面
    this._bluetooth_device = plus.android.importClass("android.bluetooth.BluetoothDevice");
    this.blue_client = _bluetooth_adapter.getDefaultAdapter();//蓝牙Adapter
    this.intent_filter = new _intent_filter()
    this.searchBtnBack = null//搜索按钮回调
    this.searchListBack = null//搜索结果回调
    this.connectBack = null//连接回调
    this.searchList = []//搜索到的设备列表
    this.bondedList = []//连接到的设备
    this.connectingDevice = null//要连接到的设备
    this.blueData = new BlueData()
    this._init()
    this._registerListener()
    // #endif
  }

  _init() {
    if (!this.blue_client.isEnabled()) {
      this.blue_client.enable();
    }
    console.log("this.blue_client.isEnabled()", this.blue_client.isEnabled())
    // 申请定位权限
    plus.android.requestPermissions(['android.permission.ACCESS_FINE_LOCATION'], function (e) {
      if (e.deniedAlways.length > 0) {	//权限被永久拒绝
        // 弹出提示框解释为何需要定位权限，引导用户打开设置页面开启
        console.log('Always Denied!!! ' + e.deniedAlways.toString());
      }
      if (e.deniedPresent.length > 0) {	//权限被临时拒绝
        // 弹出提示框解释为何需要定位权限，可再次调用plus.android.requestPermissions申请权限
        console.log('Present Denied!!! ' + e.deniedPresent.toString());
      }
      if (e.granted.length > 0) {	//权限被允许
        //调用依赖获取定位权限的代码
        console.log('Granted!!! ' + e.granted.toString());
      }
    }, function (e) {
      console.log('Request Permissions error:' + JSON.stringify(e));
    });
  }

  _registerListener() {//注册监听
    this.bluetooth_receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', {
      onReceive: (context, intent) => {
        console.log("_registerListener===")
        this._blueToothListener(context, intent)
      }
    })//蓝牙广播
    this.intent_filter.addAction(this._bluetooth_device.ACTION_FOUND);
    this.intent_filter.addAction(this.blue_client.ACTION_DISCOVERY_STARTED);
    this.intent_filter.addAction(this.blue_client.ACTION_DISCOVERY_FINISHED);
    this.intent_filter.addAction(this.blue_client.ACTION_STATE_CHANGED);
    this.intent_filter.addAction(this._bluetooth_device.ACTION_BOND_STATE_CHANGED);
    this.intent_filter.addAction(this._bluetooth_device.ACTION_PAIRING_REQUEST);
    //注册监听
    this.main_activity.registerReceiver(this.bluetooth_receiver, this.intent_filter);
  }

  _blueToothListener(context, intent) {//蓝牙监听事件
    plus.android.importClass(intent); //通过intent实例引入intent类，方便以后的‘.’操作
    console.log("_registerListener", intent.getAction())//获取action
    let blue_device = intent.getParcelableExtra(this._bluetooth_device.EXTRA_DEVICE);
    switch (intent.getAction()) {
      case BlueState.DISCOVERY_FINISHED:
        // this.main_activity.unregisterReceiver(this.bluetooth_receiver); //取消监听
        this._backSearchBtn({text: '搜索设备', disabled: false})
        break
      case BlueState.DISCOVERY_FOUND:
        this._updateSearchList(blue_device)
        break
      case BlueState.PAIRING_REQUEST:
        this._setPairData(blue_device)
        break
      case BlueState.BOND_STATE_CHANGED:
        this._getBindDevice()
        break
      case BlueState.STATE_CHANGED:
        if (this.blue_client.isEnabled()) this.startSearch()
        break
    }
  }

  _backSearchBtn({text, disabled}) {
    if (this.searchBtnBack) this.searchBtnBack({text, disabled})
  }

  _backSearchList() {
    if (this.searchListBack) this.searchListBack(this.searchList)
  }

  _updateSearchList(device) {//更新设备列表
    // console.log("_updateSearchList===", device)
    let address = device.getAddress(), name = device.getName()
    let device_in = this.searchList.find(item => item.address === address)
    if (device_in) return
    this.searchList.push({address, name, device})
    // console.log("_updateSearchList===", this.searchList)
    this._backSearchList(this.searchList)
  }

  /**
   * 设置蓝牙数据回调
   */
  setBackListener({searchListBack = null}) {
    console.log("setBackListener")
    if (searchListBack != null) this.searchListBack = searchListBack
    this._getBindDevice()
  }

  /**
   * 开始搜索蓝牙设备
   */
  startSearch({searchBtnBack = null}) {
    console.log("startSearch")
    if (searchBtnBack != null) this.searchBtnBack = searchBtnBack
    if (!this.blue_client.isEnabled()) {
      this.blue_client.enable();
      return
    }
    this.blue_client.startDiscovery(); //开启搜索
    this._backSearchBtn({text: "正在搜索请稍候", disabled: true})
  }

  /**
   * 绑定蓝牙设备
   */
  bondDevice({deviceItem, connectBack}) {
    let {device} = deviceItem
    let createBond = device.createBond()
    this.connectingDevice = device
    this.connectBack = connectBack
    console.log(createBond)
  }

  /**
   * 发送数据
   */
  async sendData(device) {
    console.log("sendData")
    let UUID = plus.android.importClass("java.util.UUID");
    let uuid = UUID.fromString("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
    // let bluetoothSocket = device.createRfcommSocket();
    let bluetoothSocket = device.createRfcommSocketToServiceRecord(uuid);
    // let bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(uuid);
    console.log(bluetoothSocket)
    plus.android.importClass(bluetoothSocket);
    console.log("bluetoothSocket", bluetoothSocket)
    if (!bluetoothSocket.isConnected()) {
      console.log('检测到设备未连接，尝试连接....');
      try {
        await bluetoothSocket.connect();
      } catch (e) {
        console.log(e)
      }
    }
    let isConnected = bluetoothSocket.isConnected()
    console.log("连接...", isConnected)
    if (isConnected) {
      console.log('设备已连接');
      let outputStream = bluetoothSocket.getOutputStream();
      plus.android.importClass(outputStream);
      let string = "打印测试\r\n";
      let bytes = plus.android.invoke(string, 'getBytes', 'gbk');
      outputStream.write(bytes);
      outputStream.flush();
      device = null //这里关键
      bluetoothSocket.close(); //必须关闭蓝牙连接否则意外断开的话打印错误
    }
  }

  _setPairData(device) {
    console.log("_setPairData", device)
    let string = plus.android.importClass("java.lang.String");
    let string1 = new string("123456")
    console.log("_setPairData", string1)
    let bytes = plus.android.invoke(string1, 'getBytes', 'gbk');
    console.log("_setPairData", bytes)
    let setPin = device.setPin(bytes)
    console.log("_setPairData", setPin)
    if (setPin && device.getAddress() == this.connectingDevice.getAddress()) alert("连接成功！")
  }

  _getBindDevice() {
    this.bondedList = []
    let deviceList = this.blue_client.getBondedDevices()
    plus.android.importClass(deviceList);
    let iterator = deviceList.iterator();
    plus.android.importClass(iterator);
    while (iterator.hasNext()) {
      let device = iterator.next();
      plus.android.importClass(device);
      let name = device.getName(), address = device.getAddress(), connected = device.isConnected()
      this.bondedList.push({name, address, connected, bonded: true, device})
    }
    let containDevice = this.connectingDevice && this.bondedList.filter(item => item.connected && item.address === this.connectingDevice.address)
    if (containDevice && this.connectBack) {
      this.connectBack("连接成功！")
      this.connectBack = null
    }
    this._updateBondedList()
  }

  _updateBondedList() {
    console.log("_updateBondedList", this.bondedList)
    this.bondedList.forEach(item => this._updateSearchList(item.device))
    this.searchList = this.searchList.map(item => {
      let bondedDevice = this.bondedList.find(device => device.address === item.address)
      bondedDevice = bondedDevice ? bondedDevice : {}
      let {connected, bonded} = bondedDevice
      return {...item, connected, bonded}
    })
    this._backSearchList(this.searchList)
  }
}
